//
//  HRPermanentThread.m
//  runloop让线程保活封装版
//
//  Created by Hello Cai on 2021/7/27.
//

#import "HRPermanentThread.h"

@interface HRThread : NSThread
@end

@implementation HRThread

-(instancetype)initWithHRBlock:(void (^)(void))block{
    void (^inBlock)(void) = [block copy];
    HRThread *thread = (HRThread *)[[NSThread alloc] initWithTarget:self selector:@selector(task:) object:inBlock];
    return thread;
}

-(void)task:(void (^)(void))block{
    if(block)
    {
        block();
    }
}

- (void)dealloc
{
    NSLog(@"%s", __func__);
}

@end

@interface HRPermanentThread ()
@property (nonatomic, strong)HRThread *innerThread;
@property (assign, nonatomic, getter=isStoped) BOOL stopped;
@end

@implementation HRPermanentThread

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.stopped = NO;
        
        __weak typeof(self) weakSelf = self;
        self.innerThread = [[HRThread alloc] initWithHRBlock:^{
            
            NSLog(@"%@----begin----", [NSThread currentThread]);
            [[NSRunLoop currentRunLoop] addPort:[[NSPort alloc] init] forMode:NSDefaultRunLoopMode];
            
            while (weakSelf && !weakSelf.isStoped) {
                [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
            }
            NSLog(@"%@----end----", [NSThread currentThread]);
        }];
        [self.innerThread start];
    }
    return self;
}

-(void)executeBlock:(void (^)(void))block{
    if (!self.innerThread || !block) return;
    
    [self performSelector:@selector(task:) onThread:self.innerThread withObject:block waitUntilDone:NO];
}

-(void)task:(void (^)(void))block{
    block();
}

-(void)stop{
    // waitUntilDone:YES表示等performSelector执行完后，程序才会往下走.
    // 这里必须填YES
    [self performSelector:@selector(innerStop) onThread:self.innerThread withObject:nil waitUntilDone:YES];
}

-(void)innerStop{
    // 设置标记为NO
    self.stopped = YES;
    
    // 停止RunLoop
    CFRunLoopStop(CFRunLoopGetCurrent());
    
    self.innerThread = nil;
}

- (void)dealloc
{
    NSLog(@"%s", __func__);
    [self stop];
}

@end
